package com.sta.oldman.tcp;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.sta.oldman.coder.SerialPortListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.websocketx.*;
import io.netty.util.concurrent.ScheduledFuture;

import java.util.concurrent.TimeUnit;

public class NettyServerHandler extends SimpleChannelInboundHandler<Object> {
    private static final ObjectMapper objectMapper = new ObjectMapper();
    // 用于存储定时任务的引用，以便后续可以取消
    private ScheduledFuture<?> sendTask;

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 处理 HTTP 请求 (WebSocket 握手阶段)
        if (msg instanceof FullHttpRequest) {
            handleHttpRequest(ctx, (FullHttpRequest) msg);
        }
        // 处理 WebSocket 帧
        else if (msg instanceof WebSocketFrame) {
            handleWebSocketFrame(ctx, (WebSocketFrame) msg);
        }
    }

    private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) {
        // 处理 HTTP 请求 (WebSocket 握手)
        // 这里可以添加自定义的握手处理逻辑
    }

    private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
        // 处理不同类型的 WebSocket 帧
        if (frame instanceof TextWebSocketFrame) {
            // 处理文本消息
            TextWebSocketFrame textFrame = (TextWebSocketFrame) frame;
            String message = textFrame.text();
            System.out.println("收到客户端消息: " + message);

            // 回复消息给客户端
            ctx.channel().writeAndFlush(new TextWebSocketFrame("服务器收到消息: " + message));
        } else if (frame instanceof CloseWebSocketFrame) {
            // 处理关闭请求
            cancelSendTask(); // 取消定时发送任务
            ctx.channel().writeAndFlush(frame.retain());
            ctx.close();
        } else if (frame instanceof PingWebSocketFrame) {
            // 处理 Ping 消息 (心跳)
            ctx.channel().writeAndFlush(new PongWebSocketFrame(frame.content().retain()));
        } else if (frame instanceof PongWebSocketFrame) {
            // 处理 Pong 消息
            System.out.println("收到 Pong 消息");
        } else {
            // 其他类型的帧 (二进制帧等)
            String message = "unsupported frame type: " + frame.getClass().getName();
            throw new UnsupportedOperationException(message);
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx)  {
        System.out.println("客户端连接: " + ctx.channel().remoteAddress());

        // 发送欢迎消息
        ctx.writeAndFlush(new TextWebSocketFrame("欢迎连接到 WebSocket 服务器!"));


        // 启动定时任务，每5秒发送一次TCPMsg格式的数据
        sendTask = ctx.channel().eventLoop().scheduleAtFixedRate(() -> {
            try {
                String msg = SerialPortListener.getAndClearFrames();
                for (String str : msg.split("\n")) {
                    System.out.println(msg);
                    ctx.channel().writeAndFlush(new TextWebSocketFrame(str));
                }
            } catch (Exception e) {
                e.printStackTrace();
                ctx.close();
            }
        }, 1, 1, TimeUnit.SECONDS); // 1秒后开始，每5秒执行一次
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户端断开连接: " + ctx.channel().remoteAddress());
        cancelSendTask(); // 确保连接关闭时取消定时任务
        ctx.close();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        cancelSendTask(); // 发生异常时取消定时任务
        ctx.close();
    }

    // 取消定时发送任务的辅助方法
    private void cancelSendTask() {
        if (sendTask != null && !sendTask.isCancelled()) {
            sendTask.cancel(true);
            sendTask = null;
        }
    }
}